package com.translation.dao;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.translation.C3P0DataSourceFactory;
import com.translation.dao.sql.QueryCache;

public class BaseDAO {

	protected static DataSource dataSource;
	protected static QueryCache queryCache;

	static {
		dataSource = C3P0DataSourceFactory.getDataSource();
		queryCache = new QueryCache();
	}

	public static QueryCache getQueryCache() {
		return queryCache;
	}

	public BaseDAO() {
	}

	public void selectQuery(String query, Selector selector) throws SQLException, IOException {
		String sql = queryCache.getQuery(query);
		this.select(sql, selector);
	}

	public void select(String sql, Selector selector) throws SQLException, IOException {
		Connection c = null;
		try {
			c = dataSource.getConnection();
			PreparedStatement st = c.prepareStatement(sql);
			selector.setParams(st);
			ResultSet rs = st.executeQuery();
			while (rs.next()) {
				selector.row(rs);
			}
			st.close();
		} finally {
			if (c != null) {
				c.close();
			}
		}
	}

	public void namedBatch(String name, Batch batch) throws SQLException, IOException {
		String sql = queryCache.getQuery(name + ".sql");
		this.batch(sql, batch);
	};

	public void batch(String sql, Batch batch) throws SQLException, IOException {
		Connection c = null;
		try {
			c = dataSource.getConnection();
			c.setAutoCommit(false);
			PreparedStatement st = c.prepareStatement(sql);
			int batchSize = batch.getSize();
			boolean nextRow = true;
			while (nextRow) {
				int rows = 0;
				while (rows++ < batchSize && (nextRow = batch.next())) {
					batch.setParams(st);
					st.addBatch();
				}
				int[] result = st.executeBatch();
				nextRow = batch.result(result, st) && nextRow;
			}
			st.close();
			c.commit();
		} catch (SQLException e) {
			batch.error(e);
			c.rollback();
			throw e;
		} finally {
			if (c != null) {
				c.close();
			}
		}
	}

}
